package com.ipay.aop;

import com.alibaba.fastjson.JSON;
import com.ipay.util.UUIDSnowFlake;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

/**
 * @author ：前世小和尚（xiaopingzhang8@creditease.cn）
 * @Description ：MDC日志流水切入基于AOP代理
 * @ClassName ：MDCLogAspectj
 * @Company ：普信恒业科技发展（北京）有限公司
 * @date ：2018/4/11 14:56
 */
@Aspect
@EnableAspectJAutoProxy
@ComponentScan(value = {"com.ipay.service"})
@Component
public class MDCLogAspectJ {
    private static final Logger log = LoggerFactory.getLogger(MDCLogAspectJ.class);

    @Before("execution(public * com.ipay.service.*.*(..))")
    public void begin(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        String className = signature.getDeclaringTypeName();
        String methodName = signature.getName();
        joinPoint.getArgs();
        String tradeId = UUIDSnowFlake.getUUId();
        if (MDC.get("tradeId") == null) {
            MDC.put("tradeId", tradeId);
            MDC.put("startTime", String.valueOf(System.currentTimeMillis()));
        }
        log.info("invoke class->{},method->{},param->{}", className, methodName, JSON.toJSONString(joinPoint.getArgs()));

    }

    @AfterReturning(value = "execution(public * com.ipay.service.*.*(..))", returning = "ret")
    public void doReturn(Object ret) {
        log.info("response->{}", JSON.toJSONString(ret));
    }

    @After("execution(public * com.ipay.service.*.*(..))")
    public void end(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        String className = signature.getDeclaringTypeName();
        String methodName = signature.getName();
        if (MDC.get("startTime") != null) {
            try {
                log.info("invoke class->{},method->{},耗时->{}毫秒", className, methodName, System.currentTimeMillis() - Long.valueOf(MDC.get("startTime")));
            } catch (Exception e) {
            }
        }
        if (MDC.get("tradeId") != null) {
            MDC.remove("tradeId");
            MDC.remove("startTime");
        }
    }

}
